iT邦幫忙

2023 iThome 鐵人賽

DAY 5
0
Modern Web

TypeScript 啟動!系列 第 5

[Day 05] TypeScript 你所不知道的基礎型別

  • 分享至 

  • xImage
  •  

型別基礎

讓我們窺探 TypeScript 有的型別吧,它們含有什麼數值,我們可以幹嘛。

Any

any 是型別的惡魔,只要付出代價,它全都可以實現;但天下沒有白吃的午餐,除非別無選擇,不然千萬不要向它請求。

在 TypeScript 中,每個東西在編譯的時候都必須有一個型別,而 any 就是當我(工程師)與 TypeScript (型別檢查系統)都看不出某個東西究竟需要什麼型別的時候,會預設的型別。千萬記得我們必須防止這件事情發生,因為它全部都可以實現,一定會出現無法想像的 Bug 。

// any demon!!!
let num: any = 123;
let list: any = ['demon']; // 陣列:未來會詳細說明,但它並沒有辦法跟數字做運算。

console.log( num + list); // 顯然不應該運作,但是 TypeSciprt 會當作沒看到,並盡可能運算出來。

並且 TypeScript 會當作沒看到,因為 any + any 是非常合理的,不過我們還是有辦法請 TypeScript 來幫忙的,還記得之前提到的設定檔案嗎?

// tsconfig.json
{
    ...
    "noImplicitAny": true,
    ...
}

只需要將註解的部分打開,那 TypeScript 就會抱怨隱含的 any 。

unknown

不找 any 要找 unknow!

雖然跟 any 一樣,它可以代表任何數值型別。但在你對它進行檢查之前(確認之前),TypeScript 是不會讓你使用 unknown 型別的,才能讓程式碼有炸彈的地方減少。

unknown 支援哪些運算呢( == 、 === 、 ||&& 、 ? 、 !)

== v.s === :=== 才是真的 == ,先記得想要比較東西的時候用 === 就對了。
JavaScript 的原始基礎設計會讓有些東西的運算有神秘的結果,請允許我在後期的時候再跟大家介紹一下。

那先上範例。


let num: unknown = 30; // unknown
let bool = num === 123; // boolean
let error = num + 10; // Error

https://ithelp.ithome.com.tw/upload/images/20230920/20163107RKwKEwLDPI.png

它可以代表任何數值型別。但在你對它進行檢查之前(確認之前),換句話說就是要確認之後才能用。

let num: unknown = 30;
let bool = num === 123;
if (typeof num === 'number'){ // 檢查之後
    let error = num + 10; // 那就沒問題了!
}

typeof 是一個可以知道變數為什麼型別的函數。

透過上面的例子,我們可以知道 3件事情。

  1. TypeScript 不會把某個東西推理成 unknown ,必須我們註記才能這樣子。
  2. 可以比較型別為 unknown 的值。
  3. 雖然我可以假設 num 變數為 unknown 型別,但是我在做運算得時候,還是得先去檢查確認之後才行。

boolean

boolean 型別只有兩個值: true 與 false。

前面已經有提到過了,這邊就先貼一下之前的,後面再放神秘操作。

let TRUE: boolean = true;
let FALSE: boolean = false;

console.log( TRUE || FALSE); // true
console.log( TRUE && FALSE); // false
console.log( !TRUE); // false,!會讓變數 TRUE 反過來,所以就是 false。

https://ithelp.ithome.com.tw/upload/images/20230920/20163107CaXOJqeDWv.png

https://ithelp.ithome.com.tw/upload/images/20230920/20163107MEmxbZfUP2.png

牛刀小試

let a = true; // boolean
const b = true; // true
let c: boolean = true; // boolean
let d: true = true; // true
let e: false = true; // Error,型別 false 不可以指定給型別 true

從上面 TypeScript 中可以發現

  • 我可以讓 TypeScript 推論我的數值是 boolean ( a 變數)。
  • 我可以讓 TypeScript 推論我的數值是一個的定的 boolean ( b 變數)。神秘?
  • 可以明確告訴 TypeScript 我的數值是 boolean( c 變數) 。
  • 可以明確告訴 TypeScript 我的數值是 bool( d, e 變數)。

其中第 2、4 種的情況特別有趣 XD,基本上限制了 b, d, e 變數可能的數值之後,範圍從 boolean 值所小為特定的 boolean 。這種形況稱為 type literal

型別字面值( type literal ):僅代表單一值的型別。

其中第 2 種情況(b 變數),const 是一個常數,不可以再改變,因此給予他 true 型別後它也會被 TypeScript 推論到 true 上,進而與型別字面值(type literal)定義相同。

當然型別字面值如果能確定,就會能提取出額外的安全性,畢竟代表單一值的型~也正因為這樣… JavaScript 的世界真的很奇妙呢。

number

是集合所有數字的集合:整數、浮點數、正數、負數、 Infinity 、 NaN 等等。運算就是常見的 ( + 、 - 、 * 、 / 、% ) 與神秘的( || 、 && 、 ? )。

let a = 123; // number
let b = Infinity * 0.10 // number
const c = 456; // 456
let d = a < b; // boolean
let e: number = 10; // number
let f: 10.123 = 10.123; // 10.123
let g: 10.123 = 10; // Error, 型別 10 不能指定給 10.123。

從上面範例我們可以得出幾個重要概念。

  • 讓 TypScript 推論變數是 number( a, b 變數)
  • 用 const (常數),特意讓 TypeScript 自己推論成特定 number ( c 變數)
  • 我可以明確告訴 TypeScript 我的變數是 number 型別 ( e 變數)
  • const 代表常數,所以 TypeScript 會自己推論成特定 number ( c 變數)

const 可用 NaN Infinity -Infinty 作為型別字面值嗎?( type literal )

當然浮點數、Infinity 、 NaN 會是一個可以講很多的部分,所以我們就稍微提到就好,畢竟我們得先著重註記型別上面。

  • 浮點數: JavaScript 運算依照 IEEE754(某個規範解說範例),計算過程會轉換二進制,所以在做浮點數運算的時候要特別小心。
console.log((0.1+0.2) === 0.3); // false
  • NaN( Not a Number ):「它是 number 型別,但不是 number」,簡單來說就是 JavaScript 算不出來他就會丟給我們 NaN。
console.log(0/0); // 返回 NaN,因为0不能當除数
console.log(NaN === NaN); // 只會回傳 false,注意一下,少數 「自己 != 自己」QQ
  • Infinity:當今天數字過大或過小的話,就會回傳 Infinity 來表示。 number 可以處理 2^53的整數。

bigint

當今天數字超過 2^53 的話,就需要使用這個來處理大型整數。大致上操作就跟 number 一樣了~

並非所有的 JavaScript 都有支援處理 bigint ,如果需要則要確認一下~

let a = 123n;
let b: bigint = 123n;

可能會出現錯誤訊息「bigint literals are not available when targeting lower than es2020.ts」這時候就需要做額外操作,在設定檔案修正一下。最快的方式就是 tsc --target es2020 test.ts

{
  "compilerOptions": {
     "target": "es2020",
  }
}

symbol

Symbol(’test’):創一個具有特定名稱,這個 symbol 會是唯一的且不會等於(以 == 或 === 進行比較)。即時兩個名稱一模一樣也不行唷。

let a = Symbol('a'); // symbol
let b: symbol = Symbol('b'); // symbol
console.log(a === b); // boolean, false

運行一樣會報錯誤訊息,可以先嘗試 tsc --target es2020 test.ts。

unique symbol:創建唯一。

const c = Symbol('c'); // typeof c
const d: unique symbol = Symbol('d'); // typeof d
let e: unique symbol = Symbol('e'); // Error,創建唯一的時候一定要用 const。畢竟才可以維持唯一呀~
  • 如果創建 unique symbol ,TypeScript 會顯示 typeof yourVariableName,而不是 typeof c 之類的。
  • 我可以明確註記 const d 變數型別為 unique symbol。
  • unique symbol 永遠與自己相等。

上一篇
[Day 04] TypeScript 談論型別
下一篇
[Day 06] TypeScript 你所不知道的物件型別
系列文
TypeScript 啟動!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言